#pragma once

namespace Melting
{
	namespace Parallel
	{
		class AtomicCounter
		{
		public:
			inline AtomicCounter( void )
			:    miValue( 0 )
			{
			}
			inline AtomicCounter( INT32 _iValue )
			:    miValue( _iValue )
			{
			} 
			
			inline INT32 Get( void ) const
			{
	//			Parallel::MemoryBarrier(); 
				return miValue;
			}		
			inline INT32 Set( INT32 _iValue )
			{
				return AtomicSwap( &miValue, _iValue );
			}
			inline INT32 Increment( void )
			{
				return AtomicIncrement( &miValue );
			}
			inline INT32 Decrement( void )
			{
				return AtomicDecrement( &miValue );
			}
			inline INT32 Add( INT32 _iAmount )
			{
				return AtomicAdd( &miValue, _iAmount );
			}
			inline INT32 Sub( INT32 _iAmount )
			{
				return AtomicSub( &miValue, _iAmount );
			}
		private:
			volatile INT32 miValue;
		}; 



		
		//template <typename T>
	 //   class AtomicInteger
	 //   {
	 //   public:
	 //       inline AtomicInteger( void )
	 //       :    miValue( 0 )
	 //       {			
		//		STATIC_ASSERT( sizeof(T) == 4, AtomicInteger_works_only_with_32bits_types );
	 //       }

	 //       inline AtomicInteger( T _iValue )
	 //       :    miValue( _iValue )
	 //       {
	 //       } 
		//	
	 //       inline T Get( void ) const
	 //       {
	 //           return miValue;
	 //       }		
		//	inline T Set( T _iValue )
		//	{
		//		return AtomicSwap( &miValue, _iValue );
		//	}
	 //       inline T Increment( void )
	 //       {
	 //           return AtomicIncrement( &miValue );
	 //       }
	 //       inline T Decrement( void )
	 //       {
	 //           return AtomicDecrement( &miValue );
	 //       }
	 //       inline T Add( T _iAmount )
	 //       {
	 //           return AtomicAdd( &miValue, _iAmount );
	 //       }
	 //       inline T Sub( T _iAmount )
	 //       {
	 //           return AtomicSub( &miValue, _iAmount );
	 //       }
	 //   private:
	 //       volatile T miValue;
	 //   }; 

		//typedef AtomicInteger<INT32>		AtomicCounter; 

		//template<class T>
		//class AtomicPtr
		//{
	 //       inline AtomicPtr( void )
	 //       :    mpValue( NULL )
	 //       {			
		//		STATIC_ASSERT( sizeof(T*) == 4, AtomicPtr_works_only_with_32bits_pointers );
	 //       }

	 //       inline AtomicPtr( T* _pValue )
	 //       :    mpValue( _pValue )
	 //       {
	 //       } 
		//	
	 //       inline T* Get( void ) const
	 //       {
	 //           return mpValue;
	 //       }		
		//	inline T* Set( T* _pValue )
		//	{
		//		return AtomicSwap( &mpValue, _pValue );
		//	}

	 //   private:
	 //       volatile T* mpValue;
		//};

	}// namespace Parallel
}// namespace Melting